<template>
  <lay-container fluid class="container-box">
    <lay-split-panel>
      <lay-split-panel-item>
        <lay-tree
          :data="deptTreeDataSource"
          :tail-node-icon="false"
          :onlyIconControl="true"
          v-model:selectedKey="selectedDeptKey"
          @node-click="deptHandleClick"
        />
      </lay-split-panel-item>
      <lay-split-panel-item>
    <!--查询条件-->
    <lay-card>
      <lay-form :model="searchModel" ref="searchForm" size="sm" labelWidth="80" class="search-form">
        <lay-form-item label="用户账号" prop="userAccount" mode="inline" >
          <lay-input v-model="searchModel.userAccount" placeholder="请输入" :allow-clear="true"/>
        </lay-form-item>
        <lay-form-item label="用户名称" prop="userName" mode="inline">
          <lay-input v-model="searchModel.userName" placeholder="请输入" :allow-clear="true"/>
        </lay-form-item>
        <lay-form-item label="状态" prop="state" mode="inline">
          <lay-select v-model="searchModel.state" placeholder="请选择" :allow-clear="true">
            <lay-select-option value="0" label="正常"></lay-select-option>
            <lay-select-option value="1" label="禁用"></lay-select-option>
          </lay-select>
        </lay-form-item>
        <lay-form-item mode="inline"  v-permission="['sys:user:list']">
          <lay-button type="primary" @click="search" prefix-icon="layui-icon-search">
            查询
          </lay-button>
          <lay-button @click="searchReset" prefix-icon="layui-icon-refresh">
            重置 
          </lay-button>
        </lay-form-item>
      </lay-form>
   
      <!-- table表格 -->
      <div class="table-box">
        <lay-table
          :page="page"
          :columns="columns"
          :id="id"
          :loading="loading"
          :default-toolbar="['filter','print']"
          :data-source="dataSource"
          :autoColsWidth="true"
          :resize="true"
          v-model:selected-key="selectedKey"
          @change="search"
          @sortChange="sortChange">

          <!--状态列-->
          <template #state="{ row }">
            <lay-switch 
              v-model="row.state" 
              :onswitch-value = 0
              :unswitch-value = 1 
              @change="changeState($event,row)">
            </lay-switch>
          </template>

          <!--操作列-->
          <template v-slot:operator="{ row }">
            <lay-space>
              <lay-button v-permission="['sys:user:info']" @click="toInfo(row)" prefix-icon="layui-icon-tips" type="normal" size="sm">
                详情
              </lay-button>
              <lay-dropdown updateAtScroll>
                <lay-button type="primary" suffix-icon="layui-icon-down" size="sm">更多</lay-button>
                <template #content>
                    <lay-dropdown-menu>
                      <lay-dropdown-menu-item v-permission="['sys:user:edit']" @click="toSave('编辑', row)">
                        <template #prefix><lay-icon type="layui-icon-edit"/></template>
                        <template #default>编辑</template>
                      </lay-dropdown-menu-item>
                      <lay-dropdown-menu-item v-permission="['sys:user:remove']" @click="remove(row)">
                        <template #prefix><lay-icon type="layui-icon-delete"/></template>
                        <template #default>删除</template>
                      </lay-dropdown-menu-item>
                      <lay-dropdown-menu-item v-permission="['sys:user:reset-pwd']" @click="toResetPwd(row)">
                        <template #prefix><lay-icon type="layui-icon-password"/></template>
                        <template #default>重置密码</template>
                      </lay-dropdown-menu-item>
                      <lay-dropdown-menu-item v-permission="['sys:user:roles']" @click="toAssigningRoles(row)">
                        <template #prefix><lay-icon type="layui-icon-user"/></template>
                        <template #default>分配角色</template>
                      </lay-dropdown-menu-item>
                    </lay-dropdown-menu>
                </template>
              </lay-dropdown>
            </lay-space>
          </template>

          <!--工具栏-->
          <template v-slot:toolbar>
            <lay-button v-permission="['sys:user:add']" @click="toSave('新增用户')" type="primary" size="sm">
              <lay-icon class="layui-icon-addition"/>
              新增
            </lay-button>
            <lay-button v-permission="['sys:user:export']" @click="exportData" size="sm">
              <lay-icon class="layui-icon-export"/>
              导出
            </lay-button>
          </template>
        </lay-table>
      </div>
    </lay-card>

    <!-- 保存窗口 -->
    <lay-layer v-model="visibleSaveLayer" :title="saveLayertitle" :btn="saveLayerBtn" :area="['720px', '430px']" :maxmin="true">
        <lay-form class="model-form" :model="saveModel" ref="saveForm" :rules="saveFormRules" size="sm" label-width="60">
          <lay-form-item v-if="!saveModel.id" label="账号" prop="loginAccount" mode="inline" :required="true">
            <lay-input v-model="saveModel.loginAccount" placeholder="请输入"/>
          </lay-form-item>

          <lay-form-item v-if="!saveModel.id" label="密码" prop="loginPassword" mode="inline" :required="true">
            <lay-input type="password" password v-model="saveModel.loginPassword" placeholder="请输入"/>
          </lay-form-item>

          <lay-form-item label="姓名" prop="userName" mode="inline" :required="true">
            <lay-input v-model="saveModel.userName" placeholder="请输入"/>
          </lay-form-item>

          <lay-form-item label="所属部门" prop="deptId" mode="inline" :required="true">
            <lay-tree-select v-model="saveModel.deptId" :data="deptTreeDataSource"/>
          </lay-form-item>

          <lay-form-item label="手机号" prop="phone" mode="inline" >
            <lay-input v-model="saveModel.phone" placeholder="请输入"/>
          </lay-form-item>

          <lay-form-item label="邮箱" prop="email" mode="inline">
            <lay-input v-model="saveModel.email" placeholder="请输入"/>
          </lay-form-item>

          <lay-form-item label="性别" prop="sex" mode="inline" :required="true">
            <lay-radio-group name="action" v-model="saveModel.sex">
              <lay-radio v-model="saveModel.sex" name="action" :value="0" label="男"/>
              <lay-radio v-model="saveModel.sex" name="action" :value="1" label="女"/>
              <lay-radio v-model="saveModel.sex" name="action" :value="2" label="未知"/>
            </lay-radio-group>
          </lay-form-item>

          <lay-form-item label="简介" prop="remark">
            <lay-textarea placeholder="请输入简介" v-model="saveModel.remark"/>
          </lay-form-item>
        </lay-form>
    </lay-layer>

    <!-- 详情窗口 -->
    <lay-layer v-model="visibleInfoLayer" title="详情" :btn="infoLayerBtn" :area="['730px', '500px']" :maxmin="true" >
        <lay-form class="model-form" :model="infoModel" size="sm" label-width="100" :pane="true">
          <lay-form-item label="id" prop="id" mode="inline">
            <lay-input v-model="infoModel.id" readonly/>
          </lay-form-item>

          <lay-form-item label="账号" prop="loginAccount" mode="inline">
            <lay-input v-model="infoModel.loginAccount" readonly/>
          </lay-form-item>

          <lay-form-item label="姓名" prop="userName" mode="inline" >
            <lay-input v-model="infoModel.userName" readonly />
          </lay-form-item>

          <lay-form-item label="所属部门" prop="deptName" mode="inline" >
            <lay-input v-model="infoModel.deptName" readonly />
          </lay-form-item>

          <lay-form-item label="手机号" prop="phone" mode="inline" >
            <lay-input v-model="infoModel.phone" readonly />
          </lay-form-item>

          <lay-form-item label="邮箱" prop="email" mode="inline">
            <lay-input v-model="infoModel.email" readonly />
          </lay-form-item>

          <lay-form-item label="性别" prop="sexName" mode="inline">
            <lay-input v-model="infoModel.sexName" readonly />
          </lay-form-item>

          <lay-form-item label="状态" prop="stateName" mode="inline">
            <lay-input v-model="infoModel.stateName" readonly />
          </lay-form-item>
          
          <lay-form-item label="类型" prop="typeName" mode="inline">
            <lay-input v-model="infoModel.typeName" readonly />
          </lay-form-item>

          <lay-form-item label="创建时间" prop="createTime" mode="inline">
            <lay-input v-model="infoModel.createTime" readonly />
          </lay-form-item>
         

          <lay-form-item label="简介" prop="remark">
            <lay-textarea v-model="infoModel.remark" readonly/>
          </lay-form-item>
        </lay-form>
    </lay-layer>

    <!-- 重置密码窗口 -->
    <lay-layer v-model="visibleResetPwdLayer" title="重置密码" :btn="resetPwdLayerBtn" :area="['400px', '200px']" :maxmin="true" >
        <lay-form class="model-form" :model="saveModel" ref="resetPwdForm" :rules="saveFormRules" size="sm" label-width="100" :pane="true">
          <lay-form-item label="新密码" prop="loginPassword" mode="inline" :required="true">
            <lay-input type="password" password v-model="saveModel.loginPassword" placeholder="请输入新密码" />
          </lay-form-item>
        </lay-form>
    </lay-layer>

    <!-- 分配角色窗口 -->
    <lay-layer v-model="visibleAssigningRolesLayer" title="分配角色" :btn="assigningRolesLayerBtn" :area="['400px', '200px']" :maxmin="true" >
      <div class="model-form">
        <lay-space>
          <lay-checkbox-group v-model="assignedRoleModel.roleIds" v-for="role in roleList">
            <lay-checkbox name="role" skin="primary" :value="role.id">{{role.roleName}}</lay-checkbox>
          </lay-checkbox-group>
        </lay-space>
      </div>
    </lay-layer>
 
  </lay-split-panel-item>
</lay-split-panel>
</lay-container>
</template>
<script setup lang="ts">

import { ref, reactive ,onMounted} from 'vue'
import { layer} from '@layui/layui-vue'
import { pageApi,saveApi,removeApi,exportApi,infoApi,updateStateApi,resetPasswordApi,assigningRolesApi,queryAssignedRoleApi} from '../../../api/module/system/sys-user'
import { listApi } from '../../../api/module/system/sys-role'
import { treeApi } from '../../../api/module/system/sys-dept'
import { Rules} from 'async-validator';

//加载函数
onMounted(() => {
  //查询数据
  search();
  //加载部门树
  loadDeptTree();
})

//主键id
const id = ref<string>("id")
//表格数据源
const dataSource = ref<any[]>([])
//选中数据行id
const selectedKey = ref<string>()
//选中部门id
const selectedDeptKey = ref<string>()
//表格是否加载中
const loading = ref<boolean>(false)
//保存表单
const saveForm = ref<any>()
//重置密码表单
const resetPwdForm = ref<any>()
//查询条件表单
const searchForm = ref<any>()
//是否显示更新窗口
const visibleSaveLayer = ref<boolean>(false)
//是否显示详情窗口
const visibleInfoLayer = ref<boolean>(false)
//是否显示分配角色窗口
const visibleAssigningRolesLayer = ref<boolean>(false)
//是否重置密码窗口
const visibleResetPwdLayer = ref<boolean>(false)
//新增/编辑窗口标题
const saveLayertitle = ref<string>()
//查询条件数据
const searchModel = ref<any>({})
//保存数据
const saveModel = ref<any>({})
//详情数据
const infoModel = ref<any>({})
//角色列表数据
const roleList = ref<any>([])
//部门树
const deptTreeDataSource = ref<any>([])
//分页参数数据
const page = reactive<any>({
  current: 1,
  limit: 10, 
  total: 0 
})

//排序参数数据
const sortQuery = reactive<any>({
  sortField:'createTime',
  sortType:'desc'
})

//分配角色保存数据
const assignedRoleModel= reactive<any>({
  userId:null,
  roleIds:[]
})

//表格字段
const columns = ref<any[]>([
  { title: '序号', width: '30px', type: 'radio', fixed: 'left',hide:"true"},
  { title: '账号', width: '60px', key: 'loginAccount', fixed: 'left', sort: 'desc'},
  { title: '头像', width: '30px', key: 'avatar', customSlot: 'avatar',hide:"true"},
  { title: '姓名', width: '60px', key: 'userName', sort: 'desc'},
  { title: '部门', width: '80px', key: 'deptName', sort: 'desc'},
  { title: '类型', width: '60px', key: 'typeName', sort: 'desc'},
  { title: '手机', width: '80px', key: 'phone', sort: 'desc',hide:"true"},
  { title: '状态', width: '40px', key: 'state', customSlot: 'state'},
  { title: '邮箱', width: '100px', key: 'email',hide:"true"},
  { title: '性别', width: '40px', key: 'sexName',hide:"true"},
  { title: '创建人', width: '80px', key: 'createUserName',hide:"true"},
  { title: '创建时间', width: '100px', key: 'createTime'},
  { title: '操作', width: '120px', key: 'operator',fixed: 'right',customSlot: 'operator'}
])

//保存表单验证规则
const saveFormRules = ref<Rules>({
  loginAccount : {
    type :  'string',
    min : 2,
    max : 20
  },
  userName : {
    type :  'string',
    min : 2,
    max : 30
  },
  loginPassword : {
    type :  'string',
    min : 6,
    max : 30
  },
  email : {
    type : 'email',
  },
  phone : {
    type :  'string',
    min : 11,
    max : 11
  }
})

//保存窗口按钮
const saveLayerBtn = ref([{
    text: "提交",
    callback: () => {
      //提交要保存的数据
      saveForm.value.validate((isValidate: any, model: any, errors: any) => {
        if(!isValidate){
          return;
        } 
        saveApi(model).then(({ data, code, msg }) => {
          if (code == 200) {
            visibleSaveLayer.value = false
            search();
          }
        })
      })
    }
},{
    text: "取消",
    callback: () => {
      //关闭保存窗口
      saveForm.value.reset()
      visibleSaveLayer.value = false
    }
}])


//详情窗口按钮
const infoLayerBtn = ref([{
    text: "关闭",
    callback: () => {
      //详情窗口关闭
      visibleInfoLayer.value = false
    }
}])


//重置密码窗口按钮
const resetPwdLayerBtn = ref([{
    text: "提交",
    callback: () => {
      //提交重置密码的数据
      resetPwdForm.value.validate((isValidate: any, model: any, errors: any) => {
        if(!isValidate){
          return;
        } 
        resetPasswordApi(model).then(({ data, code, msg }) => {
          if (code == 200) {
            visibleResetPwdLayer.value = false
            search();
          }
        })
      })
    }
},{
    text: "取消",
    callback: () => {
      //关闭重置密码窗口
      resetPwdForm.value.reset()
      visibleResetPwdLayer.value = false
    }
}])


//分配角色窗口按钮
const assigningRolesLayerBtn = ref([{
    text: "提交",
    callback: () => {
      //提交数据
      assigningRolesApi(assignedRoleModel)
      .then(({ data, code, msg }) => {
        if (code == 200) {
          visibleAssigningRolesLayer.value = false
          search();
        }
      })
    }
},{
    text: "取消",
    callback: () => {
      //关闭窗口
      visibleAssigningRolesLayer.value = false
    }
}])


//查询数据
const search = async() => {
  loading.value = true
  await loadDataSource();
  loading.value = false
}

//选中部门事件
const deptHandleClick = (node:any)=>{
  searchModel.value.deptId = node.id;
  search()
}

//加载部门树
const loadDeptTree = () => {
  treeApi({})
    .then(({data, code, msg}) => {
      if (code == 200) {
        deptTreeDataSource.value = data
      }
    })
}

//排序查询
const sortChange = (sortField: string, sortType: string) => {
  if(sortType){
    sortQuery.sortField = sortField;
    sortQuery.sortType = sortType;
    //查询数据
    search();
  }
}

//导出数据
const exportData = () => {
  loading.value = true
  exportApi(Object.assign(searchModel.value,{pageNum:page.current,pageSize:page.limit},sortQuery));   
  loading.value = false
}

//清除查询条件
const searchReset = () => {
  searchForm.value.reset();
}


//显示保存窗口
const toSave = (text: any, row?: any) => {
  saveLayertitle.value = text
  if (row) {
    infoApi(row.id)
    .then(({ data, code, msg }) => {
      if (code == 200) {
        saveModel.value = data;
        //显示保存窗口
        visibleSaveLayer.value = true
      }
    })
  } else {
    saveModel.value = {sex:0}
    //显示保存窗口
    visibleSaveLayer.value = true
  }

}

//显示重置密码窗口
const toResetPwd = (row:any) => {
  //显示重置密码窗口
  saveModel.value = {
    id:row.id
  }
  visibleResetPwdLayer.value = true
}

//显示详情窗口
const toInfo = (row: any) =>{
  infoApi(row.id)
    .then(({ data, code, msg }) => {
      if (code == 200) {
        infoModel.value = data;
        visibleInfoLayer.value = true
      }
    })
  
}

//显示分配角色窗口
const toAssigningRoles = (row: any)=>{
  assignedRoleModel.userId = row.id
  //查询角色列表
  listApi(null)
  .then(({ data, code, msg }) => {
      if (code == 200) {
        roleList.value = data
        //查询用户已分配角色
        queryAssignedRoleApi(row.id)
        .then(({ data, code, msg }) => {
          if (code == 200) {
            assignedRoleModel.roleIds = data;
            //显示窗口
            visibleAssigningRolesLayer.value = true;
          }
        })
      }
    })
  
}

//加载表格数据
const loadDataSource = () => {
return new Promise<void>((resolve) => {
  let queryParam = Object.assign(searchModel.value,{pageNum:page.current,pageSize:page.limit},sortQuery);
  pageApi(queryParam)
    .then(({ data, code, msg }) => {
      if (code == 200) {
        dataSource.value = data.list;
        page.total = data.total;
      }
    }).finally(()=>{
        resolve();
    })
  })
}

//删除数据
const remove = (row:any) => {
  layer.confirm(`确认删除用户[${row.loginAccount}]？`, {
    title: '提示',
    btn: [{
        text: '确定',
        callback: (id: any) => {
          removeApi(row.id).then(({ data, code, msg }) => {
            if (code == 200) {
              layer.msg('删除成功!')
              layer.close(id)
              search();
            } 
          })
        }
      },{
        text: '取消',
        callback: (id: any) => {
          layer.close(id)
        }
      }]
  })
}

//修改状态
const changeState = (val:number,row: any) => {
  updateStateApi({id:row.id,state:val})
    .then(({ data, code, msg }) => {
        if (code == 200) {
          //toSearch();
        }
    })
}

</script>

<style scoped>

</style>../../../api/module/sys-user